/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "ui列表.h"

#include "ui文本编辑.h"
#include "..\UI.h"




static uint16 gDraw列表框_属性ID = 0;
static C_下拉列表框* g当前打开列表组件 = nullptr;


static void f_draw列表框选中交点(C_列表框* box) {
	uint32 选中数量 = box->m_当前选中项.size();
	auto e = box->f_get更新部件();
	if (选中数量) {
		mat3X2 mat;
		box->m_当前选项焦点绘制.f_alloc(选中数量);
		for (uint32 i = 0; i < 选中数量; ++i) {
			uint32 id = box->m_当前选中项[i];
			mat.row0 = e.m_W[id]->m_Pos;
			mat.row1 = e.m_W[id]->m_Size;
			mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
			box->m_当前选项焦点绘制.f_set单色填充(i, mat, S_UI主题::uic_菜单焦点色, S_Widget预设图元::m_圆角矩形);
		}
	}
	else {
		box->m_当前选项焦点绘制.f_Close();
	}
}

static bool f_列表框鼠标滚轮(C_Widget* self, const S_鼠标& 鼠标) {
	C_列表框* box = dynamic_cast<C_列表框*>(self);

	f_布局_扩展视口纵向滚动(self->m_父部件, self, C_Widget::g_鼠标.lZ * 40);

	return true;
}

static bool on_列表框项部件鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_列表框* box = dynamic_cast<C_列表框*>(self->m_父部件);

	vec2 size = { box->m_Size.x, float32(box->m_行高度) };
	mat3X2 mat;
	mat.row0 = self->m_Pos;
	mat.row1 = size;
	mat.row2 = { 1,0 };
	

	return false;
}

static bool on_列表框项部件鼠标退出(C_Widget* self, const S_鼠标& 轮值) {
	C_列表框* 父部件 = dynamic_cast<C_列表框*>(self->m_父部件);

	/*vec2 size = { 父部件->m_Size.x, 父部件->m_行高度 };
	mat3X2 mat;
	mat.row0 = self->m_Pos;
	mat.row1 = size;
	mat.row2 = { 1,0 };
	f_vg_set变换(父部件->m_画布, gDraw列表框_鼠标焦点变换ID, 0, mat);*/

	return false;
}

static bool f_文件项选中(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_列表框* box = dynamic_cast<C_列表框*>(self->m_父部件);
	
	box->m_当前选中项.clear();
	box->m_当前选中项.push_back(self->m_实例ID);


	std::vector<std::wstring> files;
	for (auto& i : box->m_当前选中项) {
		auto& e = box->m_列表数据[i];
		files.push_back(e.m_item[0]);
	}


	f_draw列表框选中交点(box);

	if(box->mf_项选中回调) box->mf_项选中回调(box, files);

	return true;
}

static bool f_文件项双击选中(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_列表框* box = dynamic_cast<C_列表框*>(self->m_父部件);
	
	box->m_当前选中项.clear();
	box->m_当前选中项.push_back(self->m_实例ID);



	std::vector<std::wstring> files;
	for (auto& i : box->m_当前选中项) {
		auto& e = box->m_列表数据[i];
		files.push_back(e.m_item[0]);
	}
	box->mf_项选中回调(box, files);


	return true;
}





static void f_列表框布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_列表框* box = dynamic_cast<C_列表框*>(self);
	
	vec2	size = { box->m_Size.x, float32(box->m_行高度) };
	//uint8	列数 = box->m_GPU参数IDs.size() + 1;

	if (num) {
		vec2 pos = box->m_扩展视口属性->m_中心;

		std::wstring texts;
		for (uint32 i = 0; i < num; ++i) {
			w[i]->f_setPos(pos);
			w[i]->f_setSize(size);

			pos.y += box->m_行高度;
		}

		self->m_Size.y = box->m_行高度 * num;
	}
	else {
		self->m_Size.y = size.y;
	}
}

static void f_draw列表框(C_Widget* self, S_2D画布* 画布) {
	C_列表框* box = dynamic_cast<C_列表框*>(self);

	box->m_背景绘制.m_属性 = f_vg_gen属性(画布);

	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_背景绘制.m_属性);
	box->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_条纹);
	

	gDraw列表框_属性ID = f_vg_gen属性(画布);

	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, gDraw列表框_属性ID);
	box->m_当前选项焦点绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);
	
	auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	box->m_文字绘制.f_Draw(画布, &字体, gDraw列表框_属性ID);
	box->m_图标绘制.f_Draw单色(画布, gDraw列表框_属性ID, S_UI主题::ui_默认图标);
}


static void f_列表框变换修改(C_Widget* self) {
	C_列表框* box = dynamic_cast<C_列表框*>(self); 
	uint32 num = self->f_get子部件数量();

	bool 参数重置 = false;

	S_2D顶点属性 属性{};
	属性.m_比例 = {1,1};
	属性.m_间隔 = S_UI主题::ui_文字间隔;
	属性.m_渐变数量 = box->m_行高度;
	f_vg_set属性(box->m_画布, gDraw列表框_属性ID, 属性);

	属性.m_偏移 = self->m_扩展视口属性->m_中心;
	f_vg_set属性(box->m_画布, box->m_背景绘制.m_属性, 属性);


	mat3X2 mat;
	mat.row0 = { 0,0 };
	mat.row1 = self->m_Size;
	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	
	S_LineProp 线属性 = { 1.0, f_PackData4X8(box->m_颜色A), f_PackData4X8(box->m_颜色B)};
	box->m_背景绘制.f_alloc(1);
	box->m_背景绘制.f_set单色线(0, mat, 线属性, S_Widget预设图元::m_圆角矩形);
	


	auto e = self->f_get更新部件();


	
	#define DEF_字符数量 128
	box->m_文字绘制.f_alloc(num, DEF_字符数量);
	box->m_图标绘制.f_alloc(num);
	for (uint32 i = 0; i < num; ++i) {
		mat.row0 = e.m_W[i]->m_Pos;
		mat.row1 = e.m_W[i]->m_Size;
		mat.row2 = {};

		auto name = box->m_列表数据[i].m_item[0];
		mat.row0.x = e.m_W[i]->m_Size.y + 20;
		box->m_文字绘制.f_绘制文本({ mat.row0, mat.row1 }, S_UI主题::uic_文字颜色, i, name, E_对齐方式::e_左对齐, 1.01);
		//assert (name.size() < 48);
			
		mat.row0 = e.m_W[i]->m_Pos + e.m_W[i]->m_Size.y * 0.5;
		mat.row1.x = mat.row1.y = e.m_W[i]->m_Size.y * 0.8f;
		mat.row2 = {};
		mat.row0.x += 10;
		box->m_图标绘制.f_set(box->m_列表数据[i].m_ico, i, mat, box->m_列表数据[i].m_ico_color);
	}
	
	f_draw列表框选中交点(box);
}

C_列表框::C_列表框(S_UI创建环境& ctx, uint8 列数量, E_列表显示模式 模式) : C_Widget(&ctx), m_列数(列数量) {
	m_列表显示模式 = 模式;
	
	f_widget_开启视口属性(this);

	//mf_鼠标滚轮 = nullptr;
	mf_鼠标滚轮 = f_列表框鼠标滚轮;
	
	mf_DrawFun = f_draw列表框;
	mf_布局Fun = f_列表框布局;
	mf_变换修改 = f_列表框变换修改;

	m_是否多选 = false;
	mf_项选中回调 = nullptr;

	const auto& font = f_surface_get字体库(ctx, S_UI主题::ui_默认字体);
	m_行高度 = uint32(font.m_字号 * 1.8 * ctx.m_DPI);

	m_颜色A = S_UI主题::uic_列表行A;
	m_颜色B = S_UI主题::uic_列表行B;
}

C_列表框::~C_列表框() {
}


void C_列表框::f_填充列表(std::vector<S_列表填充数据>& data) {
	m_列表数据 = data;

	uint32 num = data.size();
	uint32 oldNum = m_子组件.size();

	if (oldNum) {
		m_当前选项焦点绘制.f_Close();
		//f_清楚索引子组件();
	}

	if (num > oldNum) {
		for (uint32 i = oldNum; i < num; ++i) {
			C_Widget* item = new C_Widget;

			item->mf_鼠标进入 = on_列表框项部件鼠标进入;
			item->mf_鼠标离开 = on_列表框项部件鼠标退出;
			item->mf_鼠标按键点击 = f_文件项选中;
			item->m_实例ID = i;

			f_添加子组件(item);

		}
	}else if (oldNum > num) {
		for (uint32 i = num; i < oldNum; ++i) {
			f_销毁子组件(-1);
		}
	}

	for (uint32 i = 0; i < num; ++i) {
		f_addItem(data[i], i);
	}

	m_当前选中项.clear();
	m_Size.y = num * m_行高度;
	
	m_绘制属性更新 = true;
}

C_Widget* C_列表框::f_addItem(const S_列表填充数据& data, uint32 offset) {
	
	uint32 oldNum = m_子组件.size();
	if (offset >= m_列表数据.size()) {
		m_列表数据.push_back(data);

		C_Widget* item = new C_Widget;

		item->mf_鼠标进入 = on_列表框项部件鼠标进入;
		item->mf_鼠标离开 = on_列表框项部件鼠标退出;
		item->mf_鼠标按键点击 = f_文件项选中;
		item->m_实例ID = f_get子部件数量();

		f_添加子组件(item);

		return item;
	}
	else {
		m_列表数据[offset] = data;
	}
	

	return nullptr;
}

void C_列表框::f_delItem(S_列表填充数据& data, uint32 offset) {
	
}

void C_列表框::f_clearItem() {
	f_widget_remove子部件(this, 0, m_列表数据.size());
	m_列表数据.clear();
	m_当前选中项.clear();
}

std::vector<std::string> C_列表框::f_构建选中文件(std::string root) {
	std::vector<std::string> files;

	if (root.back() != 47 && root.back() != 92) {
		root += '/';
	}

	uint32 offset = 0;
	for (auto& i : m_当前选中项) {
		auto& e = m_列表数据[i];
		files.push_back(root + f_WStringToString(e.m_item[0]));
	}

	return files;
}


void f_ui_列表框_添加列表项(C_Widget* self, const S_列表填充数据& data, int32 位置) {
	C_列表框* box = static_cast<C_列表框*>(self);

	box->m_当前选中项.clear();
	if (uint32(位置) >= box->m_列表数据.size()) {
		位置 = box->m_列表数据.size();
		box->m_列表数据.push_back(data);
	}
	else {
		box->m_列表数据.insert(box->m_列表数据.begin() + 位置, data);
	}
	box->m_当前选中项.push_back(位置);
	

	C_Widget* item = new C_Widget;
	item->mf_鼠标进入 = on_列表框项部件鼠标进入;
	item->mf_鼠标离开 = on_列表框项部件鼠标退出;
	item->mf_鼠标按键点击 = f_文件项选中;
	item->m_实例ID = box->f_get子部件数量();

	box->f_添加子组件(item, 位置);

	auto e = box->f_get更新部件();
	for (uint32 i = 0; i < e.m_Num; ++i) {
		e.m_W[i]->m_实例ID = i;
	}

	box->f_setH(e.m_Num * box->m_行高度);

	if(box->mf_项选中回调) box->mf_项选中回调(box, box->m_列表数据[位置].m_item);
}

int32 f_ui_列表框_移除列表项(C_Widget* self, int32 位置) {
	C_列表框* box = static_cast<C_列表框*>(self);

	if (!box->m_列表数据.size()) {
		return -1;
	}
	if (uint32(位置) >= box->m_列表数据.size()) {
		box->m_列表数据.pop_back();
	}
	else {
		box->m_列表数据.erase(box->m_列表数据.begin() + 位置);
	}

	box->m_当前选中项.clear();

	box->f_销毁子组件(位置);
	
	auto e = box->f_get更新部件();
	for (uint32 i = 0; i < e.m_Num; ++i) {
		e.m_W[i]->m_实例ID = i;
	}

	box->f_setH(e.m_Num * box->m_行高度);

	if (位置 >= box->m_列表数据.size()) {
		位置 = box->m_列表数据.size() - 1;
	}
	if(box->mf_项选中回调 && 位置 >= 0) box->mf_项选中回调(box, box->m_列表数据[位置].m_item);
	return e.m_Num;
}

void f_ui_列表框_填充(C_Widget* self, const std::vector<S_列表填充数据>& data) {
	C_列表框* box = static_cast<C_列表框*>(self);

	f_ui_列表框_删除项(self, -1);


	box->m_当前选中项.clear();
	box->m_列表数据.clear();
	box->m_列表数据 = data;

	uint32 num = data.size();
	if(!num) return;
	box->m_当前选中项.push_back(0);

	
	for (uint32 i = 0; i < num; ++i) {
		C_Widget* item = new C_Widget;
		item->mf_鼠标进入 = on_列表框项部件鼠标进入;
		item->mf_鼠标离开 = on_列表框项部件鼠标退出;
		item->mf_鼠标按键点击 = f_文件项选中;
		item->m_实例ID = box->f_get子部件数量();

		box->f_添加子组件(item);
	}
	box->f_setH(num * box->m_行高度);

	if(box->mf_项选中回调) box->mf_项选中回调(box, box->m_列表数据[0].m_item);
}

int32 f_ui_列表框_取当前选中ID(C_Widget* self) {
	C_列表框* box = static_cast<C_列表框*>(self);
	if (box->m_当前选中项.size()) {
		return box->m_当前选中项.front();
	}
	//return box->m_列表数据.size();
	uint32 num = box->m_列表数据.size();
	if (num) return num - 1;
	//else 
	return -1;
}

S_列表填充数据 f_ui_列表框_取当前选中项(C_Widget* self) {
	C_列表框* box = static_cast<C_列表框*>(self);
	if (box->m_当前选中项.size()) {
		auto item = box->m_列表数据[box->m_当前选中项.front()];
		return item;
	}
	return S_列表填充数据();
}

S_列表填充数据 f_ui_列表框_取选(C_Widget* self, int32 id) {
	C_列表框* box = static_cast<C_列表框*>(self);
	if (id >= box->m_列表数据.size()) {
		return {};
	}
	return box->m_列表数据[id];
}

uint32 f_ui_列表框_删除项(C_Widget* self, int32 s, int32 e) {
	C_列表框* box = static_cast<C_列表框*>(self);
	if (s < 0) {
		box->f_clearItem();
	}

	box->f_setH( box->m_行高度);
	return 0;
}

void f_ui_列表框_设置项(C_Widget* self, int32 位置, const S_列表填充数据& data) {
	C_列表框* box = static_cast<C_列表框*>(self);

	if (位置 >= box->m_列表数据.size()) 位置 = box->m_列表数据.size() - 1;

	box->m_列表数据[位置] = data;
	box->m_子组件[位置]->m_绘制属性更新 = true;
	box->m_绘制属性更新 = true;
}

uint32 f_ui_列表框_取项数量(C_Widget* self) {
	C_列表框* box = static_cast<C_列表框*>(self);
	return box->m_列表数据.size();
}

void f_ui_列表框_绑定项选中回调(C_Widget* self, fp_列表项选中回调_str call) {
	C_列表框* box = static_cast<C_列表框*>(self);
	box->mf_项选中回调 = call;
}











static void f_下拉列表布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self);
	
	float32 size = self->m_Size.y;

	auto e = self->f_get更新部件();
	e.m_W[0]->f_setSize({ size, size });
	e.m_W[1]->f_setSize({ size, size });
	e.m_W[2]->f_setSize({ size, size });
	e.m_W[3]->f_setSize({ size, size });

	e.m_W[0]->m_是否延展 = { false, false };
	e.m_W[1]->m_是否延展 = { true, true };
	e.m_W[2]->m_是否延展 = { false, false };
	e.m_W[3]->m_是否延展 = { false, false };
	f_HBOX布局(self, e.m_W, e.m_Num);
}

static void f_draw下拉列表(C_Widget* self, S_2D画布* 画布) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self);
	self->m_绘图模板.clear();

	box->m_背景绘制.m_属性 = f_vg_gen属性(画布);

	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_背景绘制.m_属性);
	box->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);
	//box->m_文字绘制.f_Draw文本(画布, self->m_UIctx->m_文字字号, gDraw列表框_属性ID);
	box->m_图标绘制.f_Draw单色(画布, box->m_背景绘制.m_属性, S_UI主题::ui_默认图标);

	self->m_绘图模板.push_back(&box->m_背景绘制);
	self->m_绘图模板.push_back(&box->m_图标绘制);
}


//static void f_下拉列表变换修改(C_Widget* self, mat3X2** t, uint16 num) {
//	C_下拉列表框* box = static_cast<C_下拉列表框*>(self);
//	bool 参数重置 = false;
//
//	S_2D顶点属性 属性;
//	属性.m_比例 = { 1,1 };
//	属性.m_偏移 = {};
//	属性.m_间隔 = S_UI主题::ui_文字间隔;
//	属性.m_渐变数量 = 0;
//	f_vg_set属性(box->m_画布, gDraw列表框_属性ID, 属性);
//
//
//	S_LineProp 线属性 = { 1.0, f_PackData4X8(box->m_颜色A), f_PackData4X8(box->m_颜色B)};
//
//	box->m_背景绘制.f_alloc(1);
//	mat3X2 mat;
//	mat.row0 = { 0,0 };
//	mat.row1 = self->m_Size;
//	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
//	box->m_背景绘制.f_set单色线(3, mat, 线属性, S_Widget预设图元::m_圆角矩形);
//
//	auto e = self->f_get更新部件();
//	mat.row0 = e.m_W[0]->m_Pos;
//	mat.row1 = e.m_W[0]->m_Size;
//	mat.row2 = { S_UI主题::ui_面板圆角半径, 0};
//	box->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_面板边, S_Widget预设图元::m_左圆角矩形);
//
//	mat.row0 = e.m_W[2]->m_Pos;
//	mat.row1 = e.m_W[2]->m_Size;
//	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
//	box->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_面板边, S_Widget预设图元::m_矩形);
//
//	mat.row0 = e.m_W[2]->m_Pos;
//	mat.row1 = e.m_W[2]->m_Size;
//	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
//	box->m_背景绘制.f_set单色填充(0, mat, S_UI主题::uic_面板边, S_Widget预设图元::m_右圆角矩形);
//
//
//
//
//	box->m_图标绘制.f_alloc(e.m_Num);
//	mat.row0 = e.m_W[0]->m_Pos + e.m_W[0]->m_Size.y * 0.5;
//	mat.row1.x = mat.row1.y = e.m_W[0]->m_Size.y * 0.8f;
//	mat.row2 = {};
//	box->m_图标绘制.f_set("", 0, mat, S_UI主题::uic_深白);
//	
//	//const auto& 字体 = f_surface_get字体库(*self->m_UIctx, S_UI主题::ui_默认字体);
//}







static bool on_下拉列表部件鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_列表框* box = dynamic_cast<C_列表框*>(self->m_父部件);

	vec2 size = { box->m_Size.x, float32(box->m_行高度) };
	uint32 选中数量 = box->m_当前选中项.size();

	box->m_当前选项焦点绘制.f_alloc(选中数量 + 1);

	mat3X2 mat;
	mat.row0 = self->m_Pos - box->m_扩展视口属性->m_中心;
	mat.row1 = size;
	mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	box->m_当前选项焦点绘制.f_set单色填充(选中数量, mat, S_UI主题::uic_菜单焦点色 + S_RGBA8UI{40,40,40,0}, S_Widget预设图元::m_圆角矩形);


	//auto& prop = f_prop_MapPrt(box->m_列表项);
	/*auto e = box->f_get更新部件();
	for (uint32 i = 0; i < 选中数量; ++i) {
		uint32 id = box->m_当前选中项[i];
		mat.row0 = e.m_W[id]->m_Pos;
		mat.row1 = e.m_W[id]->m_Size;
		mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
		box->m_当前选项焦点绘制.f_set单色填充(i, mat, S_UI主题::uic_菜单焦点色, S_Widget预设图元::m_圆角矩形);
	}*/


	return false;
}

static bool on_下拉列表部件鼠标退出(C_Widget* self, const S_鼠标& 轮值) {
	C_列表框* 父部件 = dynamic_cast<C_列表框*>(self->m_父部件);
	return false;
}


static bool on_下拉列表按钮鼠标进入(C_Widget* self, const S_鼠标& 鼠标) {
	self->m_颜色A = self->m_颜色A + S_RGBA8UI{50, 50, 50, 127};
	self->m_父部件->m_绘制属性更新 = true;
	return false;
}

static bool on_下拉列表按钮鼠标退出(C_Widget* self, const S_鼠标& 鼠标) {
	self->m_颜色A = self->m_颜色B;
	self->m_父部件->m_绘制属性更新 = true;
	return false;
}

static void on_列表项操作默认函数(S_Props& prop) {

}

static bool on_打开下拉列表(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self->m_父部件);
	if (!box->m_列表项.m_Type) return true;

	g当前打开列表组件 = box;

	box->m_列表->f_clearItem();
	auto& prop = f_prop_MapPrt(box->m_列表项);
	for (auto& e : prop.m_PtrItem) {
		C_Widget* item = box->m_列表->f_addItem({ "", {}, { e.m_Str } }, -1);
		item->mf_鼠标进入 = on_下拉列表部件鼠标进入;
	}


	f_widget_顶层窗口_pop(0);
	f_widget_弹出顶层窗口(box->m_列表视口);

	box->m_列表视口->f_setSize({ 200, float32(prop.m_PtrItem.size() * box->m_列表->m_行高度) });
	box->m_列表->f_setSize({ 200, float32(prop.m_PtrItem.size() * box->m_列表->m_行高度) });

	


	vec2 pos = self->m_GlobalLoc;
	pos.y -= (box->m_列表视口->m_Size.y + self->m_Size.y);
	
	f_widget_限制组件大小(box->m_列表视口);
	pos = f_widget_弹出窗口坐标矫正(box->m_列表视口, pos);

	box->m_列表视口->f_setPos(pos);
	//box->m_列表视口->m_GlobalLoc = {256,256};
	f_widget_单个部件裁剪(box->m_列表视口, { pos.x, pos.y, pos.x + box->m_列表视口->m_Size.x, pos.y + box->m_列表视口->m_Size.y }, {});
	box->m_列表视口->m_绘制属性更新 = true;
	box->m_列表->m_绘制属性更新 = true;
	return true;
}

static bool on_下拉列表项选中回调(C_Widget* self, const std::vector<std::wstring>& name) {
	C_列表框* listbox = static_cast<C_列表框*>(self);
	
	C_行编辑框* editbox = static_cast<C_行编辑框*>(g当前打开列表组件->m_文本编辑框);

	if (listbox->m_当前选中项.size()) {
		uint32 ID = listbox->m_当前选中项.back();
		auto& prop = f_prop_MapPrt(g当前打开列表组件->m_列表项);
		prop.m_当前项 = ID;
		
		auto str = prop.m_PtrItem[ID].m_Str;
		editbox->f_set文本(str);

		assert(prop.mf_元素变更);
		prop.mf_元素变更(g当前打开列表组件->m_列表项, prop, ID + E_Prop_MapPtr_项事件类型::e_项选择);
	}
	
	f_widget_顶层窗口_pop();

	g当前打开列表组件 = nullptr;
	return true;
}

static bool on_下拉列表添加项(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self->m_父部件);
	if (!box->m_列表项.m_Type) return true;

	auto& prop = f_prop_MapPrt(box->m_列表项);
	if (prop.mf_元素变更) {
		prop.mf_元素变更(box->m_列表项, prop, E_Prop_MapPtr_项事件类型::e_项添加);

		C_列表框* listBox = static_cast<C_列表框*>(box->m_列表);
		//C_Widget* item = listBox->f_addItem({ "", {}, { *prop.m_PtrItem.back().m_Str } }, -1);
		C_Widget* item = listBox->f_addItem({ "", {}, { prop.m_PtrItem.back().m_Str } }, -1);
		prop.m_当前项 = prop.m_PtrItem.size() - 1;
		item->mf_鼠标进入 = on_下拉列表部件鼠标进入;
		item->mf_鼠标离开 = on_下拉列表部件鼠标退出;

		C_行编辑框* editbox = static_cast<C_行编辑框*>(box->m_文本编辑框);
		//editbox->f_set文本(*prop.m_PtrItem.back().m_Str);
		editbox->f_set文本(prop.m_PtrItem[prop.m_当前项].m_Str);

		box->m_列表视口->f_setSize({ 200, prop.m_PtrItem.size() * 24.0f });
	}

	return true;
}

static bool on_下拉列表移除项(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self->m_父部件);
	if (!box->m_列表项.m_Type) return true;

	auto& prop = f_prop_MapPrt(box->m_列表项);
	if (prop.mf_元素变更) {
		prop.mf_元素变更(box->m_列表项, prop, E_Prop_MapPtr_项事件类型::e_项删除);

		if (prop.m_PtrItem.size()) {
			C_行编辑框* editbox = static_cast<C_行编辑框*>(box->m_文本编辑框);
			editbox->f_set文本(prop.m_PtrItem[prop.m_当前项].m_Str);
		}
	}
	return true;
}


static bool on_列表视口鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	//C_菜单* pMenu = dynamic_cast<C_菜单*>(menu->m_父部件);
	C_Widget::g_是否打开了弹出窗口 = false;
	return false;
}

static bool on_列表视口鼠标移出(C_Widget* self, const S_鼠标& 轮值) {
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self->m_父部件);
	C_Widget::g_是否打开了弹出窗口 = true;
	//创建线程
	auto hThread = CreateThread(NULL, 0, f_widget_定时关闭弹出组件, NULL, 0, NULL);
	return false;
}

static void on_Widget文本输入完成(C_Widget* self) {
	C_行编辑框* editbox = static_cast<C_行编辑框*>(self);
	C_下拉列表框* box = static_cast<C_下拉列表框*>(self->m_父部件);
	if (!box->m_列表项.m_Type) return;

	auto& prop = f_prop_MapPrt(box->m_列表项);
	//*(prop.m_PtrItem[prop.m_当前项].m_Str) = editbox->m_Text;
	prop.m_PtrItem[prop.m_当前项].m_Str = editbox->m_Text;
	if (prop.mf_元素变更) {
		prop.mf_元素变更(box->m_列表项, prop, E_Prop_MapPtr_项事件类型::e_项名称改变);
	}
}

static void on_下拉列表_滚动框布局(C_Widget* self, C_Widget** w, uint32 num) {
	w[0]->f_setW(self->m_Size.x);
}

C_下拉列表框::C_下拉列表框(S_UI创建环境& ctx, bool 可编辑) : C_Widget(&ctx) {
	C_Widget* 弹出菜单按钮 = new C_Widget;
	弹出菜单按钮->f_setSize({ 24,24 });
	弹出菜单按钮->mf_鼠标进入 = on_下拉列表按钮鼠标进入;
	弹出菜单按钮->mf_鼠标离开 = on_下拉列表按钮鼠标退出;
	弹出菜单按钮->m_颜色A = S_UI主题::uic_按钮;
	弹出菜单按钮->m_颜色B = S_UI主题::uic_按钮;
	弹出菜单按钮->m_图元 = S_Widget预设图元::m_左圆角矩形;
	f_添加子组件(弹出菜单按钮);

	

	m_文本编辑框 = new C_行编辑框(ctx);
	m_文本编辑框->mf_鼠标进入 = on_下拉列表按钮鼠标进入;
	m_文本编辑框->mf_鼠标离开 = on_下拉列表按钮鼠标退出;
	((C_行编辑框*)m_文本编辑框)->mf_文本输入完成 = on_Widget文本输入完成;
	f_添加子组件(m_文本编辑框);
	


	C_Widget* 添加项按钮 = new C_Widget;
	添加项按钮->f_setSize({ 24,24 });
	添加项按钮->mf_鼠标进入 = on_下拉列表按钮鼠标进入;
	添加项按钮->mf_鼠标离开 = on_下拉列表按钮鼠标退出;
	添加项按钮->m_颜色A = S_UI主题::uic_按钮;
	添加项按钮->m_颜色B = S_UI主题::uic_按钮;
	添加项按钮->m_图元 = S_Widget预设图元::m_矩形;

	m_移除项按钮 = new C_Widget;
	m_移除项按钮->f_setSize({ 24,24 });
	m_移除项按钮->mf_鼠标进入 = on_下拉列表按钮鼠标进入;
	m_移除项按钮->mf_鼠标离开 = on_下拉列表按钮鼠标退出;
	m_移除项按钮->m_颜色A = S_UI主题::uic_按钮;
	m_移除项按钮->m_颜色B = S_UI主题::uic_按钮;
	m_移除项按钮->m_图元 = S_Widget预设图元::m_右圆角矩形;

	f_添加子组件(添加项按钮);
	f_添加子组件(m_移除项按钮);

	mf_DrawFun = f_draw下拉列表;
	mf_布局Fun = f_下拉列表布局;


	弹出菜单按钮->mf_鼠标按键按下 = on_打开下拉列表;
	if (可编辑) {
		添加项按钮->mf_鼠标按键按下 = on_下拉列表添加项;
		m_移除项按钮->mf_鼠标按键按下 = on_下拉列表移除项;
	}


	m_列表 = new C_列表框(ctx, 1, E_列表显示模式::e_列表模式_垂直);
	m_列表->mf_项选中回调 = on_下拉列表项选中回调;

	m_列表视口 = new C_滚动框(ctx, false, true, m_列表);
	//m_列表视口 = new C_Widget(&ctx);
	m_列表->f_setSize({ 256, 512 });
	m_列表视口->f_setSize({ 256, 512 });
	m_列表视口->mf_鼠标进入 = on_列表视口鼠标进入;
	m_列表视口->mf_鼠标离开 = on_列表视口鼠标移出;
	//m_列表视口->mf_鼠标滚轮 = f_列表框鼠标滚轮;
	m_列表视口->mf_鼠标滚轮 = nullptr;
	m_列表视口->mf_布局Fun = on_下拉列表_滚动框布局;

	mf_添加项 = on_列表项操作默认函数;
	mf_移除项 = on_列表项操作默认函数;
}

C_下拉列表框::~C_下拉列表框(){
}


C_Widget* f_ui_创建下拉列表(S_UI创建环境& ctx, bool 可编辑, bool 拷贝按钮) {
	C_下拉列表框* box = new C_下拉列表框(ctx, 可编辑);

	if (拷贝按钮) {
		box->m_移除项按钮->m_ICO = "clipboard_copy";
	}
	else {
		box->m_移除项按钮->m_ICO = "删除";
	}

	return box;
}

void f_ui_绑定下拉列表属性(C_Widget* self, S_Props& prop) {
	C_下拉列表框* listbox = static_cast<C_下拉列表框*>(self);
	listbox->m_列表项 = prop;
	static_cast<C_行编辑框*>(listbox->m_文本编辑框)->m_Value = prop;

	C_列表框* listBox = static_cast<C_列表框*>(listbox->m_列表);
	listBox->f_clearItem();

	auto& p = f_prop_MapPrt(prop);
	if(p.m_当前项 >= p.m_PtrItem.size()) p.m_当前项 = 0;
	//auto& str = *p.m_PtrItem[p.m_当前项].m_Str;
	auto& str = p.m_PtrItem[p.m_当前项].m_Str;
	static_cast<C_行编辑框*>(listbox->m_文本编辑框)->f_set文本(str);
	

	listbox->m_列表->f_clearItem();
	for (auto& e : p.m_PtrItem) {
		C_Widget* item = listbox->m_列表->f_addItem({ "", {}, { e.m_Str } }, -1);
		item->mf_鼠标进入 = on_下拉列表部件鼠标进入;
	}
}

void f_ui_设置下拉列表项(C_Widget* self, int32 id) {
	C_下拉列表框* listbox = static_cast<C_下拉列表框*>(self);
	
	if (id >= 0) {
		auto item = f_ui_列表框_取选(listbox->m_列表, id);
		if (item.m_item.size()) {
			static_cast<C_行编辑框*>(listbox->m_文本编辑框)->m_Text = item.m_item[0];
		}
	}
	else {
		static_cast<C_行编辑框*>(listbox->m_文本编辑框)->m_Text = L"";
	}
	listbox->m_文本编辑框->m_绘制属性更新 = true;
}

std::wstring f_ui_get下拉列表文本(C_Widget* self) {
	C_下拉列表框* listbox = static_cast<C_下拉列表框*>(self);
	return static_cast<C_行编辑框*>(listbox->m_文本编辑框)->m_Text;
}







